home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 338_01 / bc.c < prev    next >
Text File  |  1988-02-23  |  17KB  |  783 lines

  1. /* bc.c, code building function of as68 assembler
  2.  * 
  3.  *    (C) Copyright 1982 Steve Passe
  4.  *    All Rights Reserved
  5.  *
  6.  * version 1.00
  7.  * created 10/21/82
  8.  *
  9.  * version 1.01
  10.  *
  11.  *   8/30/83 ver. 1.01 modified for Aztec ver. 1.05g smp
  12.  *   10/12/87  split into root, pass1 and pass2 parts for overlay on pdp-11
  13.  */
  14.  
  15. /* begincode */
  16.  
  17. /* includes */
  18.  
  19. #include <stdio.h>
  20. #include "as68.h"
  21.  
  22. /* externals */
  23.  
  24. extern char pass;                /* present pass number, 1 or 2 */
  25. extern unsigned    line_count;            /* line number of source file */
  26. extern long loc_counter;            /* address to assemble obj code */
  27. extern int loc_plus;                /* increment to loc counter    */
  28. extern FLAG abs_long;                /* default to absolute long add.*/
  29. extern FLAG rorg;                /* in pc relative mode */
  30. extern char label[32];            /* buffer for label from preparse */
  31. extern char instr[33];            /* buffer for mnem, psdo or macro */
  32.  
  33. extern struct _mtable mtable[];            /* mnemonic    lookup table */
  34. extern struct _mvalue mvalue[];            /* mnemonic    code table */
  35. extern struct _oprnd op1, op2;          /* structs to hold operand val */
  36. extern char code[];                /* code array */
  37.  
  38. match(mt)
  39. register struct _mtable *mt;
  40. {
  41.     register int index;                    /* index to mvalue */
  42.     int type1 = _none, type2 = _none;            /* operand types */
  43.  
  44.     op_clear(&op1);
  45.     op_clear(&op2);
  46.     if (mt->_nops >= 1 && (type1 = op_eval(&op1)) < 0) { /* legal type found? */
  47.     err_out(BAD_OP1);        /* first op bad */
  48.     }
  49.     if (mt->_nops == 2 && (type2 = op_eval(&op2)) < 0) { /* second op? */
  50.     err_out(BAD_OP2);        /* no good */
  51.     }
  52.     if (type1 < 0 || type2 < 0) {
  53.     return ERROR;                /* use NULL opcode */
  54.     }
  55.     if ((index = type_search(mt, type1, type2))    <=0) {
  56.     switch (index) {
  57.     case ILGL_OP1:
  58.         err_out(ILGL_OP1);        /* no good */
  59.         return ERROR;
  60.     case ILGL_OP2:
  61.         err_out(ILGL_OP2);        /* no good */
  62.         return ERROR;
  63.     default:
  64.         return ERROR;
  65.     }
  66.     }
  67.     return index;
  68. }
  69.  
  70. type_search(mt,    type1, type2)
  71. struct _mtable *mt;
  72. int type1;
  73. int type2;
  74. {
  75.     register int x, y;                  /* count and index */
  76.     register int t1, t2;                /* temp for array value */
  77.  
  78.     for (x = mt->_mvc, y = mt->_mvi; x; --x, ++y) { /* search */
  79.                         /* find op1 match... */
  80.     if (((t1 = mvalue[y]._optyp1) == type1)     /* if exact match */
  81.     || ((!(t1 & ~0xf0)) && (t1 & type1))) { /* or classtyp and match */
  82.                         /* search for second match */
  83.         for ( ; (mvalue[y]._optyp1 == t1) && x; --x, ++y) {
  84.         if (((t2 = mvalue[y]._optyp2) == type2) /* 2nd matches */
  85.         || ((!(t2 & ~0xf0)) && (t2 & type2))) { /* or typ & match */
  86.             return y;               /* found a match */
  87.         }
  88.         }
  89.         return ILGL_OP2;
  90.     }
  91.     }
  92.     return ILGL_OP1;
  93. }
  94.  
  95. /* mask 3 bit immediate    data from op1 over bits 3-1 of code [0] */
  96.  
  97. bbb(op)
  98. register struct _oprnd *op;
  99. {
  100.     if (op->_data & ~7) return ERR_BBB;
  101.     code[0] |= (op->_data << 1);
  102.     return NULL;
  103. }
  104.  
  105. /* first ext word holds bit number (7/31) from first operand */
  106.  
  107. bbbx(size, op)
  108. int size;
  109. struct _oprnd *op;
  110. {
  111.     switch (size) {
  112.     case 3:
  113.     if (op->_data & ~7L) return ERR_BX3;            /* range? */
  114.     case 5:
  115.     if (op->_data & ~31L) return ERR_BX5;
  116.     code[3]    = op->_data;
  117.     return 1;                        /* 1 ext word */
  118.     default:
  119.     return ERR_BX;
  120.     }
  121. }
  122.  
  123. /** mask bits 3-1 of first byte with op1, 8 = 00 */
  124.  
  125. ccc(op)
  126. register struct _oprnd *op;
  127. {
  128.     if (op->_data < 1L || op->_data > 8L) return ERR_CCC;
  129.     code[0] |= (op->_data << 1) & 0x0f;
  130. /** if (op->_data != 8L) code[0] |= op->_data << 1; **/
  131.  
  132.     return NULL;                    /* no words added */
  133. }
  134.  
  135. /* mask bits 3-1 of first byte, or bits 2-0 of second, with op reg */
  136.  
  137. rsd(byt, op)
  138. int byt;
  139. register struct _oprnd *op;
  140. {
  141.     code[byt] |= (byt) ? op->_reg : op->_reg << 1;
  142.     return NULL;
  143. }
  144.  
  145. /* register mask list from op into ext */
  146.  
  147. mmkk(order, op)
  148. char order;
  149. register struct _oprnd *op;
  150. {
  151.     register int x;
  152.     unsigned u1 = 0;
  153.     unsigned m1 = 0x0001;
  154.     unsigned m2 = 0x8000;
  155.  
  156.     switch (order) {
  157.     case '>':
  158.     code[2]    = op->_reg_list    >> 8;               /* high byte */
  159.     code[3]    = op->_reg_list;                /* low byte */
  160.     return 1;
  161.     case '<':
  162.  
  163.     for (x = 15; x >= 0; --x) {
  164.         u1 |= (op->_reg_list & (m1 << x)) ? (m2 >> x) : 0;
  165.     }
  166.  
  167.     code[2]    = u1 >> 8;            /* high byte */
  168.     code[3]    = u1;               /* low byte */
  169.     return 1;
  170.     default:
  171.     return ERR_MK;
  172.     }
  173. }
  174.  
  175. /* combined e, f, g, h, and j routines,    12/4/82    */
  176.  
  177. efghj(arg, i, op)
  178. register char arg;
  179. register int i;
  180. register struct _oprnd *op;
  181. {
  182.     int len, displ;
  183.  
  184.     switch (op->_typ) {
  185.     case _ani:                  /* (an) */
  186.     if (arg == 'g') {
  187.         code[0] |= (op->_reg << 1);
  188.         code[1] |= 0x80;
  189.     }
  190.     else {
  191.         code[1] |= (0x10 | op->_reg);
  192.     }
  193.     return NULL;
  194.     case _pd_ani:                /* -(an) */
  195.     switch (arg) {
  196.     case 'g':
  197.         code[0] |= (0x01 | op->_reg    << 1);
  198.         return NULL;
  199.     case 'j': return ERR_J;
  200.     case 'h': return ERR_H;
  201.     default:
  202.         code[1] |= (0x20 | op->_reg);
  203.         return NULL;
  204.     }
  205.  
  206.     case _ani_pi:                /* (an)+ */
  207.     switch (arg) {
  208.     case 'g':
  209.         code[0] |= (op->_reg << 1);
  210.         code[1] |= 0xc0;
  211.         return NULL;
  212.     case 'j': return ERR_J;
  213.     case 'h': return ERR_H;
  214.     default:
  215.         code[1] |= (0x18 | op->_reg);
  216.         return NULL;
  217.     }
  218.  
  219.     case _d16_ani:                /* d16(an) */
  220.     switch (arg) {
  221.     case 'e':
  222.     case 'j':
  223.         if (/**rorg**/ op->_rel_lbl) {
  224.         op->_ireg = op->_reg;            /* reg is an index */
  225.         op->_iregtyp = op->_regtyp;        /* move type */
  226.         op->_displ -= (loc_counter + 2);    /* make pc relative    */
  227.         code[1]    |= 0x3b;
  228.         return _d8_i(i,    op);            /* indexed label */
  229.         }
  230.         break;
  231.     case 'g':
  232.         code[0] |= (0x01 | op->_reg    << 1);
  233.         code[1] |= 0x40;
  234.         return _d16(i, op);
  235.     }
  236.     code[1]    |= (0x28 | op->_reg);
  237.     return _d16(i, op);
  238.  
  239.     case _d8_anx:                /* d8(an,i) */
  240.     if (arg == 'g') {
  241.         code[0] |= (0x01 | op->_reg    << 1);
  242.         code[1] |= 0x80;
  243.     }
  244.     else {
  245.         code[1] |= (0x30 | op->_reg);
  246.     }
  247.     return _d8_i(i,    op);
  248.  
  249.     case _address:    /* abs. add., short or long, or label if _rel_lbl */
  250.     switch (arg) {
  251.     case 'e':
  252.     case 'j':
  253.         if (/**rorg**/ op->_rel_lbl) {
  254.         code[1]    |= 0x3a;
  255.         op->_displ = op->_addr - (loc_counter + 2); /* rel. to pc */
  256.         return _d16(i, op);            /* finish as 'label' */
  257.         }
  258.         break;
  259.     case 'g':
  260.         code[1] |= 0xc0;
  261.         if (op->_long_val) {
  262.         code[0]    |= 0x03;
  263.         code[i++] = op->_addr >> 24;
  264.         code[i++] = op->_addr >> 16;
  265.         len = 2;
  266.         }
  267.         else {
  268.         code[0]    |= (0x01);
  269.         len = 1;
  270.         }
  271.         code[i++] = op->_addr >> 8;
  272.         code[i] = op->_addr;
  273.         return len;
  274.     }
  275.     if (op->_long_val) {
  276.         code[1] |= (0x39);
  277.         code[i++] = op->_addr >> 24;
  278.         code[i++] = op->_addr >> 16;
  279.         len = 2;
  280.     }
  281.     else {
  282.         code[1] |= (0x38);
  283.         len = 1;
  284.     }
  285.     code[i++] = op->_addr >> 8;
  286.     code[i]    = op->_addr;
  287.     return len;
  288.  
  289.     case _label:                /* relative label */
  290.     switch (arg) {
  291.     case 'g': return ERR_G;
  292.     case 'f': return ERR_F;
  293.     case 'h': return ERR_H;
  294.     default:
  295.         code[1] |= 0x3a;
  296.         op->_displ -= (loc_counter + 2);    /* rel. to pc */
  297.         return _d16(i, op);
  298.     }
  299.  
  300.     case _labeli:                /* label(i) */
  301.     switch (arg) {
  302.     case 'g': return ERR_G;
  303.     case 'f': return ERR_F;
  304.     case 'h': return ERR_H;
  305.     default:
  306.         code[1] |= 0x3b;
  307.         op->_displ -= (loc_counter + 2);    /* rel. to pc */
  308.         return _d8_i(i, op);
  309.     }
  310.  
  311.     default:
  312.     return ERR_EFGHJ;
  313.     }
  314. }
  315.  
  316. _d16(i,    op)
  317. register int i;
  318. register struct _oprnd *op;
  319. {
  320.     if ((op->_displ > 32767) || (op->_displ < -32768)) return ERR_D16;
  321.     code[i] = op->_displ >> 8;              /* displacement... */
  322.     code[i+1] = op->_displ;                /* ...into ext */
  323.     return 1;                       /* 1 ext word returned */
  324. }
  325.  
  326. _d8_i(i, op)
  327. register int i;
  328. register struct _oprnd *op;
  329. {
  330.     if ((op->_displ > 127) || (op->_displ < -128)) return ERR_D8I;
  331.     if (op->_iregtyp == 'a') code[i] |= 0x80;        /* index is addr reg */
  332.     code[i] |= (op->_ireg << 4);            /* add index reg # */
  333.     if (op->_inxl) code[i] |= 0x08;            /* mark long index size */
  334.     code[i+1] = op->_dis